package com.burt.aop;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * Description:实现日志记录功能，日志要求按天存储、日志内容包含时间戳，类名，方法名，参数列表，参数值，返回值
 * User: Burt
 * Date: 2017-06-25
 * Time: 16:32
 */
public class LogInterceptor implements MethodInterceptor {

    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
    private static SimpleDateFormat logDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    //从当前系统中获取换行符，默认是"\n"
    private static String lineSeparator = System.getProperty("line.separator", "\n");
    private Properties config = new Properties();

    public Object getInstance(Class clazz){

        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(clazz);
        //设置回调
        enhancer.setCallback(this);

        //1、生成源代码 2、编译成class文件 3、加载到JVM中，并返回被代理对象
        return enhancer.create();
    }

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        Object result = methodProxy.invokeSuper(o,objects);
        log(o, method, objects, result);
        return result;
    }

    private void log(Object o, Method method, Object[] objects,Object result) throws Exception{
        //日志拼接参考其他同学

        StringBuilder logBuilder = new StringBuilder("时间戳：");

        StringBuilder paramsBuilder = new StringBuilder();
        Class<?>[] paramTypes = method.getParameterTypes();
        for (int i = 0; i < paramTypes.length; i++) {
            paramsBuilder.append(paramTypes[i].getName()).append(" ").append(objects[i]).append(",");
        }
        if (paramsBuilder.length() > 0)
            paramsBuilder.deleteCharAt(paramsBuilder.length() - 1);

        logBuilder.append(dateFormat.format(new Date()));
        logBuilder.append(" 方法签名：");
        logBuilder.append(o.getClass().getSuperclass().getName());
        logBuilder.append(".");
        logBuilder.append(method.getName());
        logBuilder.append("(");
        logBuilder.append(paramsBuilder.toString());
        logBuilder.append(")");
        Class<?> returnType = method.getReturnType();
        if (void.class == returnType) {
            logBuilder.append(" 返回值类型：");
            logBuilder.append(returnType.getName());
            logBuilder.append(" 返回值：");
            logBuilder.append("null");
        } else {
            logBuilder.append(" 返回值类型：");
            logBuilder.append(result.getClass().getName());
            logBuilder.append(" 返回值：");
            logBuilder.append(result);
        }
        System.out.println(logBuilder.toString());
        logBuilder.append(lineSeparator);

        FileChannel fc = new RandomAccessFile(logDateFormat.format(new Date()) + ".log", "rw").getChannel();
        //定位到文件末尾
        fc.position(fc.size());
        fc.write(ByteBuffer.wrap(logBuilder.toString().getBytes()));
        fc.close();

    }
}
